package com.navercorp.pinpoint.plugin.businessMethod;

import com.navercorp.pinpoint.bootstrap.instrument.*;
import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformCallback;
import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformTemplate;
import com.navercorp.pinpoint.bootstrap.instrument.transformer.TransformTemplateAware;
import com.navercorp.pinpoint.bootstrap.logging.PLogger;
import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory;
import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin;
import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext;
import com.navercorp.pinpoint.common.trace.AnnotationKey;
import com.navercorp.pinpoint.common.trace.AnnotationKeyFactory;
import com.navercorp.pinpoint.common.trace.ServiceType;
import com.navercorp.pinpoint.common.trace.ServiceTypeFactory;

import java.security.ProtectionDomain;
import java.util.List;

/**
 * Created by Irany 2018/8/22 16:19
 */
public class GeneralConfigPlugin implements ProfilerPlugin, TransformTemplateAware {
    private final PLogger logger = PLoggerFactory.getLogger(this.getClass());
    private TransformTemplate transformTemplate;

    @Override
    public void setTransformTemplate(TransformTemplate transformTemplate) {
        this.transformTemplate = transformTemplate;
    }

    @Override
    public void setup(ProfilerPluginSetupContext context) {
        GeneralConfigConfiguration configuration = new GeneralConfigConfiguration(context.getConfig());
        if (!configuration.isEnable()) {
            return;
        }

        /*List<ConfigInfo> list = PropertyLoader.propertiesToList(null);
        addTransformers(list);*/
    }

    private void addTransformers(List<ConfigInfo> configInfos) {
        if (configInfos == null) {
            logger.error("No configuration for general config plugin");
            return;
        }
        for (ConfigInfo configInfo : configInfos) {
            addTransformer(configInfo);
        }
    }

    private void addTransformer(final ConfigInfo configInfo) {
        transformTemplate.transform(configInfo.getClazz(), new TransformCallback() {
            @Override
            public byte[] doInTransform(Instrumentor instrumentor, ClassLoader classLoader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException {
                InstrumentClass target = instrumentor.getInstrumentClass(classLoader, className, classfileBuffer);
                List<MethodArgs> methodArgsList = configInfo.getMethodArgs();
                for (MethodArgs methodArgs : methodArgsList) {
                    InstrumentMethod method = null;
//处理有参数方法
                    if (methodArgs.getArgs() != null && methodArgs.getArgs().length > 0) {
                        method = target.getDeclaredMethod(methodArgs.getMethod(), methodArgs.getArgs());
                    } else {
//处理无参数方法
                        method = target.getDeclaredMethod(methodArgs.getMethod());
                    }
                    method.addInterceptor(GeneralConfigConstants.GENERAL_CONFIG_INTERCEPTOR);
                }
                return target.toBytecode();
            }
        });
    }
}